/******************************************************************************
 *   ObjectFS - Embedded Object File-System
 *
 *   Provides a full, simple no-nonsense file-system for simple embedded devices.
 *   Written by James Walmsley, james@fullfat-fs.co.uk
 *
 *   Copyright 2010 James Walmsley
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 *
 *   Removing the above notice is illegal and will invalidate this license.
 *****************************************************************************/

 // Driver example.

/*
	A dataflash driver for the OFS filesystem.
*/

#include "ofs_types.h"
#include "ofs_error.h"
#include "../drivers/AT25DF161.h"
#include "../handles.h"

#ifdef CONFIG_SMARTSWITCH

// Simple Dataflash driver for ObjectFS

OFS_ERROR dfRead(OFS_UINT32 ulAddress, OFS_UINT32 Size, void *pBuffer, AT25DF161_HANDLE hDF) {

	hDF = GetDFHandle();
	AT25DF161_Read(hDF, ulAddress, Size, pBuffer);
	ReleaseDFHandle();
	return OFS_ERR_NONE;
}

OFS_ERROR dfWrite(OFS_UINT32 ulAddress, OFS_UINT32 Size, void *pBuffer, AT25DF161_HANDLE hDF) {

	OFS_UINT32 Write, Remaining;
	int beginOffset = (ulAddress % 256);
	unsigned char *pucData = pBuffer;

	Remaining = Size;

	while(Remaining >= 256) {
		// Deal with first any offset data.
		if(beginOffset) {
			Write = 256 - (ulAddress % 256);
			hDF = GetDFHandle();
			AT25DF161_Write(hDF, ulAddress, Write, pucData);
			ReleaseDFHandle();
			pucData += Write;
			ulAddress += Write;
			Remaining -= Write;
		} else {
			Write = 256;
			hDF = GetDFHandle();
			AT25DF161_Write(hDF, ulAddress, Write, pucData);
			ReleaseDFHandle();
			pucData += Write;
			ulAddress += Write;
			Remaining -= Write;
		}
	}

	if(Remaining) {
		hDF = GetDFHandle();
		AT25DF161_Write(hDF, ulAddress, Remaining, pucData);
		ReleaseDFHandle();
	}

	return OFS_ERR_NONE;
}

OFS_ERROR dfErase(AT25DF161_HANDLE hDF) {
	int i;
	hDF = GetDFHandle();
	for(i = 0; i < 32; i++) {
		AT25DF161_BlockErase(hDF, AT25DF161_BLOCKSIZE_64K * i, AT25DF161_BLOCKSIZE_64K);
	}
	ReleaseDFHandle();

	return OFS_ERR_NONE;
}

#endif
